#ifndef ANIMATION_H
#define ANIMATION_H

#include <QObject>
#include <QSoundEffect>
#include <QTimer>
#include "tweeny/tweeny.h"
#include "card.h"

class Animation: public QObject
{
    Q_OBJECT
public:
    explicit Animation(Card *card, const QPointF &target, int duration,
                       tweeny::easing::enumerated easing, QObject *parent = nullptr);

private:
    Card *card_;
    int z_value;
    bool flip_before_start;
    QSoundEffect *sound_effect;
    tweeny::tween<double, double> tween_;
    bool is_finished;

signals:
    void finished();

public:
    void step();
    void setSoundEffect(QSoundEffect *effect) { sound_effect = effect; }
    void setFlipBeforeStart(bool enable) { flip_before_start = enable; }
    void setStartZValue(int zValue) { z_value = zValue; }
    bool isFinished() { return is_finished; }
};

class AnimationGroup: public QObject
{
    Q_OBJECT
public:
    AnimationGroup(QObject *parent = nullptr): QObject{parent}, started(false) {}
    virtual ~AnimationGroup();

public:
    std::vector<Animation*> animations;
    std::vector<Animation*> active_animations;
    bool started;

signals:
    void finished();

public:
    virtual void step();
    virtual void addAnimation(Animation *anim) { animations.push_back(anim); }
    size_t size() { return animations.size(); }
};

class ParallelAnimationGroup: public AnimationGroup
{
    Q_OBJECT
public:
    ParallelAnimationGroup(QObject *parent = nullptr);

private:
    int delay;
    int current;
    QTimer *timer;

private slots:
    void slotTimeout();

public:
    void setDelay(int d) { delay = d; }
    void step();
};

class SequentialAnimationGroup: public AnimationGroup
{
    Q_OBJECT
public:
    SequentialAnimationGroup(QObject *parent = nullptr): AnimationGroup{parent}, current(0) {}

private:
    int current;

public:
    void step();
};

#endif // ANIMATION_H
